package gstyle;

import gstyle.compressor.BackgroundCompressor;
import gstyle.compressor.CssCompressor;

import java.util.*;

public class GeneralCompiler implements StyleCompiler {
    private List<CssCompressor> compressors = new ArrayList<CssCompressor>();
    private Map attributeCompilers = new HashMap();

    public GeneralCompiler() {
        compressors.add(new BackgroundCompressor());
    }

    public String compile(Style style) {
        StringBuffer attributesAsString = new StringBuffer();

        Map attributes = compress(style.getAttributes());
        List keys = sortKeys(attributes);

        for (Iterator iterator = keys.iterator(); iterator.hasNext();) {
            String key = (String) iterator.next();
            String value = (String) attributes.get(key);
            attributesAsString.append(compileAttribute(key, value));
        }
        return style.nameDefinition() + ("{" +
                attributesAsString.toString() +
                "}");
    }

    private List sortKeys(Map attributes) {
        List keys = new ArrayList(attributes.keySet());
        Collections.sort(keys);
        return keys;
    }

    private Map compress(Map attributes) {
        for (CssCompressor compressor : compressors) {
            attributes = compressor.compress(attributes);
        }
        return attributes;
    }

    private String compileAttribute(String key, String value) {
        return attributeCompiler(key).compile(value);
    }

    private AttributeCompiler attributeCompiler(String key) {
        if (attributeCompilers.get(key) != null) {
            return (AttributeCompiler) attributeCompilers.get(key);
        }
        return new NormalAttributeCompiler(key);
    }

}
